package net;

import java.lang.reflect.InvocationTargetException;

public class PropertyChange extends GameStateChange<Object>
{
	public PropertyChange() {
		this(null, null, null);
	}

	public PropertyChange(core.GameObject subject, String propertyName, Object propertyValue) {
		super(subject, propertyName, propertyValue);
	}

	public PropertyChange getInverse()
	{
		try {
			Object result = new GameStateChange<Object>(getSubject(), getPropertyName(), null) {
				public GameStateChange getInverse() {
					return null;
				}
				public Object execute() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
					boolean foundName = false;
					for (java.lang.reflect.Method method : getSubject().getClass().getMethods())
						if (method.getName().equals(getMethodName()) && method.getParameterTypes().length == 0)
							try {
								foundName = true;
								return method.invoke(getSubject());
							} catch (IllegalArgumentException e) {}

					if (!foundName)
						throw new NoSuchMethodException(getMethodName());
					throw new IllegalArgumentException();
				}
				protected String getMethodName() {
					return "get" + util.Util.capitalize(getPropertyName());
				}
			}.execute();
			return new PropertyChange(getSubject(), getPropertyName(), result);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return null;
	}

	protected String getMethodName() {
		return "set" + util.Util.capitalize(getPropertyName());
	}
}